{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [],
   "source": [
    "# Integer Program Problem\n",
    "'''\n",
    "here is an example to solve the following problem:\n",
    "max z = x[0]**2 + x[1]**2 + 3*x[2]**2 + 4*x[3]**2 + 2*x[4]**2 - 8*x[0] - 2*x[1] - 3*x[2] - x[3] - 2*x[4]\n",
    "s.t   x in bounds\n",
    "      A_ub * x <= b_ub\n",
    "here x is an array of integers.\n",
    "'''\n",
    "\n",
    "import numpy as np\n",
    "\n",
    "A_ub = [[1, 1, 1, 1, 1],\n",
    "        [1, 2, 2, 1, 6],\n",
    "        [2, 1, 6, 0, 0],\n",
    "        [0, 0, 1, 1, 5]]\n",
    "\n",
    "b_ub = [400, 800, 200, 200]\n",
    "bounds = [(0, 99), (0, 99), (0, 99), (0, 99)]\n",
    "\n",
    "def z(x):\n",
    "    return x[0]**2 + x[1]**2 + 3*x[2]**2 + 4*x[3]**2 + 2*x[4]**2 - 8*x[0] - 2*x[1] - 3*x[2] - x[3] - 2*x[4]"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "The best z is : 48840\n",
      "The according x is:  [52 96  0 96 20]\n"
     ]
    }
   ],
   "source": [
    "# Monte Carlo Method 蒙特卡洛方法\n",
    "\n",
    "x0 = []\n",
    "z0 = 0\n",
    "for i in range(int(1000000)):\n",
    "    x = np.random.randint(low=0, high=99, size=5, dtype=np.int64)\n",
    "    if(np.max(np.matmul(A_ub, x)-b_ub) > 0):\n",
    "        continue\n",
    "    tempz = z(x)\n",
    "    if tempz > z0:\n",
    "        z0 = tempz\n",
    "        x0 = x\n",
    "        \n",
    "print('The best z is :', z0)\n",
    "print('The according x is: ', x0)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Status: Optimal\n",
      "BeefPercent = 57.0\n",
      "ChickenPercent = 43.0\n",
      "Total Cost of Ingredients per can =  1.015\n"
     ]
    }
   ],
   "source": [
    "from pulp import *\n",
    "\n",
    "# 1. 建立问题\n",
    "prob = LpProblem(\"Bleding Problem\", LpMinimize)\n",
    "\n",
    "# 2. 建立变量\n",
    "x1 = LpVariable(\"ChickenPercent\", 0, None, LpInteger)\n",
    "x2 = LpVariable(\"BeefPercent\", 0)\n",
    "\n",
    "# 3. 设置目标函数\n",
    "prob += 0.013*x1 + 0.008*x2, \"Total Cost of Ingredients per can\"\n",
    "\n",
    "# 4. 施加约束\n",
    "prob += x1 + x2 == 100, \"PercentagesSum\"\n",
    "prob += 0.100*x1 + 0.200*x2 >= 8.0, \"ProteinRequirement\"\n",
    "prob += 0.080*x1 + 0.100*x2 >= 6.0, \"FatRequirement\"\n",
    "prob += 0.001*x1 + 0.005*x2 <= 2.0, \"FibreRequirement\"\n",
    "prob += 0.002*x2 + 0.005*x2 <= 0.4, \"SaltRequirement\"\n",
    "\n",
    "# 5. 求解\n",
    "prob.solve()\n",
    "\n",
    "# 6. 打印求解状态\n",
    "print(\"Status:\", LpStatus[prob.status])\n",
    "\n",
    "# 7. 打印出每个变量的最优值\n",
    "for v in prob.variables():\n",
    "    print(v.name, \"=\", v.varValue)\n",
    "\n",
    "# 8. 打印最优解的目标函数值\n",
    "print(\"Total Cost of Ingredients per can = \", value(prob.objective))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "Status: Optimal\n",
      "x3 = 0.0\n",
      "x_1 = 0.0\n",
      "x_2 = 6.0\n",
      "Total Cost of Ingredients per can =  -12.0\n"
     ]
    }
   ],
   "source": [
    "# 例2.8\n",
    "\n",
    "from pulp import *\n",
    "\n",
    "# 1. 建立问题\n",
    "prob = LpProblem(\"MIP\", LpMinimize)\n",
    "\n",
    "# 2. 建立变量\n",
    "x = LpVariable.dicts(name=\"x\", indexs=[1, 2], lowBound=0, cat='Continuous')\n",
    "x3 = LpVariable(name='x3', lowBound=0, upBound=1, cat='Integer')\n",
    "x[2].setInitialValue(5.5)\n",
    "x3.setInitialValue(1)\n",
    "\n",
    "# 3. 设置目标函数\n",
    "prob += -3*x[1]-2*x[2]-x3\n",
    "\n",
    "# 4. 施加约束\n",
    "prob += x[1] + x[2] + x3 <= 7\n",
    "prob += 4*x[1] + 2*x[2] + x3 == 12\n",
    "\n",
    "# 5. 求解\n",
    "prob.solve()\n",
    "\n",
    "# 6. 打印求解状态\n",
    "print(\"Status:\", LpStatus[prob.status])\n",
    "\n",
    "# 7. 打印出每个变量的最优值\n",
    "for v in prob.variables():\n",
    "    print(v.name, \"=\", v.varValue)\n",
    "\n",
    "# 8. 打印最优解的目标函数值\n",
    "print(\"Total Cost of Ingredients per can = \", value(prob.objective))"
   ]
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 4
}
